package com.hex.ds.hdrs.app.service.impl;

import com.hex.ds.hdrs.agent.po.AgentConf;
import com.hex.ds.hdrs.agent.service.AgentConfService;
import com.hex.ds.hdrs.agent.service.AgentHeartbeatLogService;
import com.hex.ds.hdrs.common.annotation.AppCodeVerification;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.helper.EchartsHelper;
import com.hex.ds.hdrs.common.utils.BaseUtil;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.cron.service.CronTaskService;
import com.hex.ds.hdrs.log.po.RunningStateLog;
import com.hex.ds.hdrs.log.service.RunningStateLogService;
import com.hex.ds.hdrs.period.job.service.QueueJobInfService;
import com.hex.ds.hdrs.period.task.service.PeriodTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author lwz
 * @date 2020-12-28
 * @des
 */
@Slf4j
@Service
public class AppStatusService {

    @Autowired
    private RunningStateLogService runningStateLogService;

    @Autowired
    private AgentConfService agentConfService;

    @Autowired
    private QueueJobInfService queueJobInfService;

    @Autowired
    private PeriodTaskService periodTaskService;

    @Autowired
    private CronTaskService cronTaskService;

    @Autowired
    private AgentHeartbeatLogService agentHeartbeatLogService;

    /**
     * 通过应用编码查询运行状态日志信息
     *
     * @param
     * @return
     */
    @AppCodeVerification(paramObject = String.class)
    public List<RunningStateLog> findRunningStateLogByAppCode(Integer pageIndex, String appCode) {
        log.info("进入RunningStateLogService的findRunningStateLogByAppCode");
        return this.runningStateLogService.findRunningStateLogByAppCode(appCode, pageIndex);
    }

    public Map findTaskRunResult(Map paramMap) {
        String timeType = (String) paramMap.get("timeType");
        String nowDate = (String) paramMap.get("nowDate");
        String appCode = (String) paramMap.get("appCode");
        Date cruntDate = HdrsDateUtil.parser(nowDate, "yyyy-MM-dd HH:mm:ss");
        List<String> times = EchartsHelper.getTimes(cruntDate, timeType);

        List<Map> cycleTaskList = this.getCycleTaskList(appCode, timeType, cruntDate);
        List<Integer> cycleTaskSuccessList = EchartsHelper.getSeriesData(cycleTaskList, times, "task_status", Const.TASK_SUCCESS);
        List<Integer> cycleTaskErrorList = EchartsHelper.getSeriesData(cycleTaskList, times, "task_status", Const.TASK_FAIL);
        List<Map> cronTaskList = this.getCronTaskList(appCode, timeType, cruntDate);
        List<Integer> cronTaskSuccessList = EchartsHelper.getSeriesData(cronTaskList, times, "exec_status", Const.CRON_TASK_SUCCESS);
        List<Integer> cronTaskErrorList = EchartsHelper.getSeriesData(cronTaskList, times, "exec_status", Const.CRON_TASK_FAIL);
        return this.getResultMap(times, cycleTaskSuccessList, cycleTaskErrorList, cronTaskSuccessList, cronTaskErrorList);
    }

    /**
     * 获取各节点并发数和资源数
     *
     * @param paramMap
     * @return
     */
    @AppCodeVerification(paramObject = LinkedHashMap.class)
    public Map findResAndConNum(Map paramMap) {
        String timeType = (String) paramMap.get("timeType");
        String nowDate = (String) paramMap.get("nowDate");
        String appCode = (String) paramMap.get("appCode");
        Date cruntDate = HdrsDateUtil.parser(nowDate, "yyyy-MM-dd HH:mm:ss");
        List<String> times = EchartsHelper.getTimes(cruntDate, timeType);

        List<AgentConf> agentConfList = this.agentConfService.qryAgentConfByAppCode(appCode);
        List<Map> dataList = this.getResAndConList(appCode, timeType, cruntDate);
        Map resultMap = this.getResAndConResultMap(times, agentConfList, dataList);
        return resultMap;
    }

    /**
     * 获取阻塞系统数据
     *
     * @param paramMap
     * @return
     */
    @AppCodeVerification(paramObject = LinkedHashMap.class)
    public Map getTaskBlockNum(Map paramMap) {
        String timeType = (String) paramMap.get("timeType");
        String nowDate = (String) paramMap.get("nowDate");
        String appCode = (String) paramMap.get("appCode");
        if (StringUtils.isBlank(appCode) && "admin".equals(BaseUtil.getUserId())){
            appCode = Const.QUEUE_CENTER_APP_CODE;
        }
        Date cruntDate = HdrsDateUtil.parser(nowDate, "yyyy-MM-dd HH:mm:ss");
        List<String> times = EchartsHelper.getTimes(cruntDate, timeType);

        List<Map> dependmentNumList=this.getDependmentNum(appCode, timeType, cruntDate);
        Map resultMap = this.getResNumAndDependNumResultMap(times,dependmentNumList);
        return resultMap;
    }


    public List<Map> getCycleTaskList(String appCode, String timeType, Date nowDate) {
        String startTime = EchartsHelper.getStartTime(nowDate, timeType);
        List<Map> resultList = new ArrayList<>();
        if ("1".equals(timeType) || "2".equals(timeType) || "3".equals(timeType)) {
            resultList = periodTaskService.getTaskListByCruuentApp(appCode, startTime);
        }
        if ("4".equals(timeType) || "5".equals(timeType)) {
            resultList = periodTaskService.getTaskListByCruuentApp2(appCode, startTime);
        }
        if ("6".equals(timeType) || "7".equals(timeType)) {
            resultList = periodTaskService.getTaskListByCruuentApp3(appCode, startTime);
        }
        return resultList;
    }

    public List<Map> getCronTaskList(String appCode, String timeType, Date nowDate) {
        String startTime = EchartsHelper.getStartTime(nowDate, timeType);
        List<Map> resultList = new ArrayList<>();
        if ("1".equals(timeType) || "2".equals(timeType) || "3".equals(timeType)) {
            resultList = cronTaskService.getTaskListByCruuentApp(appCode, startTime);
        }
        if ("4".equals(timeType) || "5".equals(timeType)) {
            resultList = cronTaskService.getTaskListByCruuentApp2(appCode, startTime);
        }
        if ("6".equals(timeType) || "7".equals(timeType)) {
            resultList = cronTaskService.getTaskListByCruuentApp3(appCode, startTime);
        }
        return resultList;
    }

    public List<Map> getDependmentNum(String appCode, String timeType, Date nowDate) {
        String startTime = EchartsHelper.getStartTime(nowDate, timeType);
        List<Map> resultList = new ArrayList<>();
        if ("1".equals(timeType) || "2".equals(timeType) || "3".equals(timeType)) {
            resultList = queueJobInfService.getBlockAndDependmentNum(appCode, startTime);
        }
        if ("4".equals(timeType) || "5".equals(timeType)) {
            resultList = queueJobInfService.getBlockAndDependmentNum2(appCode, startTime);
        }
        if ("6".equals(timeType) || "7".equals(timeType)) {
            resultList = queueJobInfService.getBlockAndDependmentNum3(appCode, startTime);
        }
        return resultList;
    }
    public Map getResultMap(List<String> times, List<Integer> cycleTaskSuccessList, List<Integer> cycleTaskErrorList,
                            List<Integer> cronTaskSuccessList, List<Integer> cronTaskErrorList) {
        Map resultMap = new HashMap();
        resultMap.put("times", times);
        resultMap.put("cycleTaskSuccessList", cycleTaskSuccessList);
        resultMap.put("cycleTaskErrorList", cycleTaskErrorList);
        resultMap.put("cronTaskSuccessList", cronTaskSuccessList);
        resultMap.put("cronTaskErrorList", cronTaskErrorList);
        return resultMap;
    }

    public List<Map> getResAndConList(String appCode, String timeType, Date cruntDate) {
        String startTime = EchartsHelper.getStartTime(cruntDate, timeType);
        List<Map> resultList = new ArrayList<>();
        if ("1".equals(timeType) || "2".equals(timeType) || "3".equals(timeType)) {
            resultList = this.agentHeartbeatLogService.getAgentHeartList(appCode, startTime);
        }
        if ("4".equals(timeType) || "5".equals(timeType)) {
            resultList = this.agentHeartbeatLogService.getAgentHeartList(appCode, startTime);
        }
        return resultList;
    }

    /**
     * 将获取到的数据转化为特定的Map集合返回
     *
     * @param times
     * @param agentConfList
     * @param dataList
     * @return
     */
    public Map getResAndConResultMap(List<String> times, List<AgentConf> agentConfList, List<Map> dataList) {
        List legend = new ArrayList();
        List seriesList = new ArrayList();
        for (AgentConf agentConf : agentConfList) {
            String agentName = agentConf.getAgentName() + "-并发数";
            legend.add(agentName);
            List seriesData = EchartsHelper.getSeriesData(dataList, times, "agent_code", agentConf.getAgentCode(), "cur_concurrence_num");
            Map seriesMap = EchartsHelper.getSeriesData(agentName, seriesData, "line");
            seriesList.add(seriesMap);
        }
        for (AgentConf agentConf : agentConfList) {
            String agentName = agentConf.getAgentName() + "-资源数";
            legend.add(agentName);
            List seriesData = EchartsHelper.getSeriesData(dataList, times, "agent_code", agentConf.getAgentCode(), "cur_res_num");
            Map seriesMap = EchartsHelper.getSeriesData(agentName, seriesData, "line");
            seriesList.add(seriesMap);
        }
        Map resultMap = new HashMap();
        resultMap.put("times", times);
        resultMap.put("legend", legend);
        resultMap.put("seriesList", seriesList);
        return resultMap;
    }

    public Map getResNumAndDependNumResultMap(List<String> times, List<Map> dependmentNumList) {
        List taskDepBlockList = EchartsHelper.getSeriesData(dependmentNumList,times,"type","0","num");
        List taskResBlockList = EchartsHelper.getSeriesData(dependmentNumList,times,"type","1","num");

        Map resultMap = new HashMap();
        resultMap.put("times", times);
        resultMap.put("taskDepBlockList", taskDepBlockList);
        resultMap.put("taskResBlockList",taskResBlockList);
        return resultMap;
    }
}
